package com.easylinkin.linkappapi.openapi.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.easylinkin.linkappapi.airconditioner.mapper.AirHostDeviceMapper;
import com.easylinkin.linkappapi.airconditioner.mapper.AirconditionDeviceRecordMapper;
import com.easylinkin.linkappapi.alarm.mapper.AlarmMapper;
import com.easylinkin.linkappapi.application.entity.Application;
import com.easylinkin.linkappapi.application.service.ApplicationService;
import com.easylinkin.linkappapi.asset.mapper.AssetMapper;
import com.easylinkin.linkappapi.calculaterule.mapper.CalculateConfigAttributeMapper;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.device.entity.Device;
import com.easylinkin.linkappapi.device.mapper.DeviceMapper;
import com.easylinkin.linkappapi.device.service.DeviceService;
import com.easylinkin.linkappapi.deviceattribute.mapper.DeviceAttributeTenantConfigMapper;
import com.easylinkin.linkappapi.deviceparm.mapper.DeviceParmDictionaryMapper;
import com.easylinkin.linkappapi.deviceservice.mapper.DeviceServiceTenantConfigMapper;
import com.easylinkin.linkappapi.deviceunit.entity.DeviceUnit;
import com.easylinkin.linkappapi.deviceunit.mapper.DeviceUnitMapper;
import com.easylinkin.linkappapi.facerecognition.mapper.PersonnelIdentifierMapper;
import com.easylinkin.linkappapi.facerecognition.mapper.PersonnelMapper;
import com.easylinkin.linkappapi.facerecognition.mapper.RecognitionRecordMapper;
import com.easylinkin.linkappapi.function.mapper.LinkappFunctionMapper;
import com.easylinkin.linkappapi.function.mapper.TenantFunctionRefAreaMapper;
import com.easylinkin.linkappapi.hcmy.mapper.AquacultureSpaceMapper;
import com.easylinkin.linkappapi.hcmy.mapper.AreasourceecologyFunctionMapper;
import com.easylinkin.linkappapi.hcmy.mapper.CarManageMapper;
import com.easylinkin.linkappapi.hcmy.mapper.LivestockFarmingMapper;
import com.easylinkin.linkappapi.investigation.mapper.InvestigationTaskDetailMapper;
import com.easylinkin.linkappapi.investigation.mapper.InvestigationTaskModelMapper;
import com.easylinkin.linkappapi.lobar.entity.emp.EmpUserBase;
import com.easylinkin.linkappapi.machinery.service.MachineryRecordService;
import com.easylinkin.linkappapi.openapi.dto.*;
import com.easylinkin.linkappapi.openapi.service.OpenApiService;
import com.easylinkin.linkappapi.openapi.util.HttpClientUtil;
import com.easylinkin.linkappapi.openapi.util.LinkThingsUtil;
import com.easylinkin.linkappapi.personality.mapper.PersonalityMapper;
import com.easylinkin.linkappapi.powerdistribution.mapper.DistributionElectricPriceMapper;
import com.easylinkin.linkappapi.rulecomponent.mapper.RuleComponentAttributeMapper;
import com.easylinkin.linkappapi.ruleengine.mapper.RuleEngineMapper;
import com.easylinkin.linkappapi.safe.dao.DangerousInfoMapper;
import com.easylinkin.linkappapi.safe.dao.HiddenDangerMapper;
import com.easylinkin.linkappapi.safe.dto.SafetyCheckCategory;
import com.easylinkin.linkappapi.safe.dto.SafetyCheckTrendDTO;
import com.easylinkin.linkappapi.safe.entity.DangerousInfo;
import com.easylinkin.linkappapi.safe.entity.HiddenDanger;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import com.easylinkin.linkappapi.security.mapper.LinkappTenantSessionConfigMapper;
import com.easylinkin.linkappapi.security.mapper.LinkappUserMapper;
import com.easylinkin.linkappapi.security.service.LinkappUserService;
import com.easylinkin.linkappapi.space.mapper.LinkappAreaMapper;
import com.easylinkin.linkappapi.tenant.entity.LinkappTenant;
import com.easylinkin.linkappapi.tenant.mapper.LinkappTenantMapper;
import com.easylinkin.linkappapi.tenant.sevice.LinkappTenantService;
import com.easylinkin.linkappapi.webcammanage.entity.DeviceAttributeStatus;
import com.easylinkin.linkappapi.webcammanage.service.DeviceAreaHandlerService;
import io.netty.util.internal.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import site.morn.rest.RestBuilders;
import site.morn.rest.RestMessage;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p></p>
 *
 * @author TongJie
 * @since 2020/10/12 15:08
 */

@Service
public class OpenApiServiceImpl implements OpenApiService {

    private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(OpenApiServiceImpl.class);

    @Resource
    private DeviceService deviceService;
    @Resource
    private DeviceMapper deviceMapper;
    @Resource
    private DeviceUnitMapper deviceUnitMapper;
    @Resource
    DeviceAreaHandlerService deviceAreaHandlerService;
    @Resource
    MachineryRecordService machineryRecordService;
    @Resource
    HiddenDangerMapper hiddenDangerMapper;
    @Resource
    AlarmMapper alarmMapper;

    @Value("${linkthing.clientId}")
    private String clientId;
    @Value("${linkthing.clientSecret}")
    private String clientSecret;
    @Value("${linkthing.grantType}")
    private String grantType;
    @Value("${linkthing.scope}")
    private String scope;
    @Value("${linkthing.tenantId}")
    private String tenantId;
    @Value("${linkthing.url.auth_url}")
    private String auth_url;
    @Value("${linkthing.url.api_url}")
    public String api_url;
    @Value("${edu.apiUrl}")
    public String apiUrl;
    @Value("${linkthing.url.token}")
    private String token;
    @Value("${linkthing.url.get_device_unit_with_device_model}")
    private String get_device_unit_with_device_model;
    @Value("${linkthing.url.device_type_list}")
    private String device_type_list;
    @Value("${linkthing.appSecret}")
    public String apiSecret;
    @Value("${linkthing.url.find_active_app_list}")
    public String find_active_app_list;
    @Value("${linkthing.keyId}")
    public String apiKey;

    @Value("${linkthing.url.get_device_unit_by_project}")
    private String get_device_unit_by_project;

    @Resource
    private LinkappTenantService tenantService;

    @Resource
    private ApplicationService applicationService;
    @Resource
    private LinkappUserService linkappUserService;
    @Resource
    private LinkappTenantMapper linkappTenantMapper;
    @Resource
    private PersonalityMapper personalityMapper;
    @Resource
    private LinkappUserMapper linkappUserMapper;
    @Resource
    private LinkappFunctionMapper functionMapper;
    @Resource
    private AssetMapper assetMapper;
    @Resource
    private AirHostDeviceMapper airHostDeviceMapper;
    @Resource
    private AirconditionDeviceRecordMapper airconditionDeviceRecordMapper;
    @Resource
    private CalculateConfigAttributeMapper calculateConfigAttributeMapper;
    @Resource
    private PersonnelMapper personnelMapper;
    @Resource
    private PersonnelIdentifierMapper personnelIdentifierMapper;
    @Resource
    private RecognitionRecordMapper recognitionRecordMapper;
    @Resource
    private InvestigationTaskDetailMapper investigationTaskDetailMapper;
    @Resource
    private InvestigationTaskModelMapper investigationTaskModelMapper;
    @Resource
    private DistributionElectricPriceMapper distributionElectricPriceMapper;
    @Resource
    private RuleComponentAttributeMapper ruleComponentAttributeMapper;
    @Resource
    private AquacultureSpaceMapper aquacultureSpaceMapper;
    @Resource
    private AreasourceecologyFunctionMapper areasourceecologyFunctionMapper;
    @Resource
    private CarManageMapper carManageMapper;
    @Resource
    private TenantFunctionRefAreaMapper tenantFunctionRefAreaMapper;
    @Resource
    private LivestockFarmingMapper livestockFarmingMapper;
    @Resource
    private LinkappTenantSessionConfigMapper linkappTenantSessionConfigMapper;
    @Resource
    private LinkappAreaMapper linkappAreaMapper;
    @Resource
    private DeviceAttributeTenantConfigMapper deviceAttributeTenantConfigMapper;
    @Resource
    private DeviceParmDictionaryMapper deviceParmDictionaryMapper;
    @Resource
    private DeviceServiceTenantConfigMapper deviceServiceTenantConfigMapper;
    @Resource
    private RuleEngineMapper ruleEngineMapper;

    /**
     * 获取Token
     */
    private TokenDTO getToken() throws UnsupportedEncodingException {
        String url = String.format("%s%s?client_id=%s&client_secret=%s&grant_type=%s&scope=%s", auth_url, token,
                clientId, clientSecret, grantType, scope);
        HttpPost httpPost = new HttpPost(url);
        StringEntity se = new StringEntity(StringUtil.EMPTY_STRING);
        se.setContentType("text/json");
        se.setContentEncoding(new BasicHeader("Content-Type", "application/json"));
        httpPost.setEntity(se);
        LOGGER.info(url);
        String str = HttpClientUtil.doPost(httpPost);
        LOGGER.info("getToken:" + str);
        TokenDTO tokenDTO = JSONObject.parseObject(str, TokenDTO.class);
        return tokenDTO;
    }

    /**
     * 获取设备型号
     */
    @Override
    public List<DeviceByProject> getDevicesByProject(String projectId, int page) throws UnsupportedEncodingException {
//        同时linkthings 设备一次请求条数
        int theGetDevicesByProjectSize = 400;
        TokenDTO tokenDTO = getToken();
        HttpGet httpGet = new HttpGet(api_url + "/api/device/v1/getDevicesByProject?id=" + projectId + "&page=" + page + "&pageSize=" + theGetDevicesByProjectSize);
        initHeader(tokenDTO, httpGet);
        StringEntity se = new StringEntity(StringUtil.EMPTY_STRING);
        se.setContentType("text/json");
        se.setContentEncoding(new BasicHeader("Content-Type", "application/json"));
        LOGGER.info("/api/device/v1/getDevicesByProject 的header:" + JSON.toJSONString(httpGet.getAllHeaders()));
        LOGGER.info("/api/device/v1/getDevicesByProject 的url:" + httpGet.getURI());
        String str = HttpClientUtil.doGet(httpGet);
//        LOGGER.info("/api/device/v1/getDevicesByProject 的请求结果是: "+str);
        if (str == null) {
            return null;
        }
        DevicesByProjectDTO devicesByProjectDTO = JSONObject.parseObject(str, DevicesByProjectDTO.class);
        if (devicesByProjectDTO != null && devicesByProjectDTO.getData() != null) {
            return devicesByProjectDTO.getData().getContent();
        }
        return null;
    }

    @Override
    public VideoLimitDTO getVideoLimitDTOByDeviceCode(String deviceCode) throws UnsupportedEncodingException {
        TokenDTO tokenDTO = getToken();
        HttpGet httpGet = new HttpGet(api_url + "/api/device/v1/videoUrlFromDown/" + deviceCode);
        initHeader(tokenDTO, httpGet);
        String result = HttpClientUtil.doGet(httpGet);
        LOGGER.info("getVideoLimitDTOByDeviceCode request result = " + result);
        if (result == null) {
            return null;
        }
        LOGGER.info("/api/device/v1/videoUrlFromDown 的header:" + JSON.toJSONString(httpGet.getAllHeaders()));
        VideData videData = JSONObject.parseObject(result, VideData.class);
        if (videData != null) {
            if ("0".equals(videData.getCode())) {
                return videData.getData();
            } else {
                return null;
            }
        }
        return null;
    }


    /**
     * 获取设备型号
     */
    @Override
    public List<DeviceUnitDTO> getDeviceUnitWithDeviceModel() throws UnsupportedEncodingException {
        TokenDTO tokenDTO = getToken();
        HttpGet httpGet = new HttpGet(api_url + get_device_unit_with_device_model);
        initHeader(tokenDTO, httpGet);
        StringEntity se = new StringEntity(StringUtil.EMPTY_STRING);
        se.setContentType("text/json");
        se.setContentEncoding(new BasicHeader("Content-Type", "application/json"));
        String str = HttpClientUtil.doGet(httpGet);
        OpenApiDeviceUnitResultDTO openApiResultDTO = JSONObject.parseObject(str, OpenApiDeviceUnitResultDTO.class);
        return openApiResultDTO.getData();
    }


    @Override
    public List<com.easylinkin.linkappapi.openapi.dto.DeviceUnit> getDeviceUnitByProject() throws UnsupportedEncodingException {
        TokenDTO tokenDTO = getToken();
        StringBuilder url = new StringBuilder(api_url);
        url.append(get_device_unit_by_project);
        url.append("?id=");
        LinkappTenant linkappTenant = tenantService.currentTenant();
        Assert.notNull(linkappTenant, "当前租户对象linkappTenant为空");
        url.append(linkappTenant.getProjectId());
        HttpGet httpGet = new HttpGet(url.toString());
        initHeader(tokenDTO, httpGet);
        StringEntity se = new StringEntity(StringUtil.EMPTY_STRING);
        se.setContentType("text/json");
        se.setContentEncoding(new BasicHeader("Content-Type", "application/json"));
        LOGGER.info("getDeviceUnitByProject: 请求url=" + JSON.toJSONString(url));
        String str = HttpClientUtil.doGet(httpGet);
        LOGGER.info("getDeviceUnitByProject请求接口是：{}，请求结果是：{}", get_device_unit_by_project, str);
        OpenApiDeviceUnitByProjectDTO openApiDeviceUnitByProjectDTO = JSONObject.parseObject(str, OpenApiDeviceUnitByProjectDTO.class);
        return openApiDeviceUnitByProjectDTO.getData();
    }

    /**
     * 前端、emp后端全局搜索均没有搜到该接口，废弃
     *
     * @param tenant
     * @return
     * @throws UnsupportedEncodingException
     */
    @Deprecated
    @Override
    public List<com.easylinkin.linkappapi.openapi.dto.DeviceUnit> getDeviceUnitByProject(LinkappTenant tenant) throws UnsupportedEncodingException {
        TokenDTO tokenDTO = getToken();
        StringBuilder url = new StringBuilder(api_url);
        url.append(get_device_unit_by_project);
        url.append("?id=");
        url.append(tenant.getProjectId());
        HttpGet httpGet = new HttpGet(url.toString());
        initHeader(tokenDTO, httpGet);
        StringEntity se = new StringEntity(StringUtil.EMPTY_STRING);
        se.setContentType("text/json");
        se.setContentEncoding(new BasicHeader("Content-Type", "application/json"));
        String str = HttpClientUtil.doGet(httpGet);
        LOGGER.info("getDeviceUnitByProject url=" + url + ", str=" + str);
        OpenApiDeviceUnitByProjectDTO openApiDeviceUnitByProjectDTO = JSONObject.parseObject(str, OpenApiDeviceUnitByProjectDTO.class);
        return openApiDeviceUnitByProjectDTO.getData();
    }

    /**
     * 获取设备类型
     */
    @Override
    public List<DeviceType> getDeviceTypeList() throws UnsupportedEncodingException {
        TokenDTO tokenDTO = getToken();
        HttpGet httpGet = new HttpGet(api_url + device_type_list);
        initHeader(tokenDTO, httpGet);
        httpGet.addHeader("tenantId", tenantId);
        StringEntity se = new StringEntity(StringUtil.EMPTY_STRING);
        se.setContentType("text/json");
        se.setContentEncoding(new BasicHeader("Content-Type", "application/json"));
        String str = HttpClientUtil.doGet(httpGet);
        //LOGGER.info("getDeviceTypeList:" + str);
        OpenApiDeviceTypeResultDTO openApiDeviceTypeResultDTO = JSONObject.parseObject(str,
                OpenApiDeviceTypeResultDTO.class);
        return openApiDeviceTypeResultDTO.getData();
    }


    @Override
    public void updateDeviceInstall(com.easylinkin.linkappapi.device.entity.Device device) {
        HttpPost httpPost = new HttpPost(String.format("%s/api/device/v1/deviceInstall", api_url));
        initHeaderDown(httpPost);
        //组织数据
        DeviceInstallDTO deviceInstallDTO = new DeviceInstallDTO();
        deviceInstallDTO.setCode(device.getCode());
        deviceInstallDTO.setLatitude(device.getLatitude());
        deviceInstallDTO.setLongitude(device.getLongitude());
        deviceInstallDTO.setLocation(device.getAreaPath());
        deviceInstallDTO.setSpaceId(StringUtils.isNotBlank(device.getAreaId()) ? device.getAreaId() : device.getSpaceId());
        deviceInstallDTO.setRemark(device.getSite());
        deviceInstallDTO.setName(device.getName());
        StringEntity se = new StringEntity(JSON.toJSONString(deviceInstallDTO), ContentType.APPLICATION_JSON);
        httpPost.setEntity(se);
        String str = HttpClientUtil.doPost(httpPost);
        LOGGER.info("updateDeviceInstall调用linkthings,参数是：{}", httpPost);
        LOGGER.info("updateDeviceInstall调用linkthings,deviceInstallDTO 参数是：{}", deviceInstallDTO);
        LOGGER.info("updateDeviceInstall调用linkthings,结果是：{}", str);
        ApiDownResultDTO result = JSON.parseObject(str, ApiDownResultDTO.class);
        if (null == result || !"200".equals(result.getCode())) {
            LOGGER.error("updateDeviceInstall调用linkthings,返回结果不满足，result：{}", result);
            throw new RuntimeException("linkthings返回结果不对！请查看日志");
        }
    }

    /**
     * 查找linkthings 活动的应用； 同步修改AEP的租户状态
     */
    @Override
    public void synchronizeTenantStatusFromLinkthings() throws UnsupportedEncodingException {
        List<LinkappTenant> linkappTenantList = tenantService.selectLinkappTenantList(new LinkappTenant());
        List<String> appIds = new ArrayList<>();

        for (LinkappTenant tenant : linkappTenantList) {
            appIds.add(tenant.getAppId());
        }
        List<String> activeAppIds = getActiveApp(appIds);

        QueryWrapper<LinkappTenant> qw = new QueryWrapper<>();
        qw.isNotNull("app_id");
        List<LinkappTenant> tenants = tenantService.list(qw);
        for (LinkappTenant tenant : tenants) {
            String oldStatus = tenant.getStatus();
            tenant.setStatus("0");
            if (activeAppIds.contains(tenant.getStatus())) {
                tenant.setStatus("1");
            }
            //  如果状态相同 则不需要修改
            if (oldStatus != null && oldStatus.equals(tenant.getStatus())) {
                continue;
            }
            tenantService.updateById(tenant);
        }
    }

    private List<String> getActiveApp(List<String> ids) throws UnsupportedEncodingException {
        TokenDTO tokenDTO = getToken();
        HttpPost httpPost = new HttpPost(find_active_app_list);
        initHeaderPost(tokenDTO, httpPost, this.apiKey, this.apiSecret, this.tenantId);
        String jsonstr = JSON.toJSONString(ids);
        StringEntity se = new StringEntity(jsonstr);
        se.setContentType("text/json");
        se.setContentEncoding(new BasicHeader("Content-Type", "application/json"));
        httpPost.setEntity(se);
        String str = HttpClientUtil.doPost(httpPost);
        //LOGGER.info("getActiveApp:" + str);
        OpenApiActiveAppListResultDTO openApiActiveAppListResultDTO = JSONObject.parseObject(str, OpenApiActiveAppListResultDTO.class);
        return openApiActiveAppListResultDTO.getData();
    }


    /**
     * 初始化HTTP头
     */
    private void initHeaderGet(TokenDTO tokenDTO, HttpGet httpGet, String apikey, String apiSecret, String tenantId) {
        LinkThingsUtil u = new LinkThingsUtil(apiKey, apiSecret);
        httpGet.addHeader("Content-Type", "application/json");
        httpGet.addHeader("Accept", "application/json");
        httpGet.addHeader("appId", apikey);
        httpGet.addHeader("appKey", clientId);
        httpGet.addHeader("accessToken", tokenDTO.getAccess_token());
        httpGet.addHeader("timestamp", u.getTimestamp());
        httpGet.addHeader("tenantId", tenantId);
        LOGGER.info("tenantId: " + tenantId);
        LOGGER.info("initHeader:" + JSONObject.toJSONString(tokenDTO));
    }

    /**
     * 初始化HTTP头
     */
    private void initHeaderPost(TokenDTO tokenDTO, HttpPost httpPost, String apikey, String apiSecret, String tenantId) {
        LinkThingsUtil u = new LinkThingsUtil(apiKey, apiSecret);
        httpPost.addHeader("Content-Type", "application/json");
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("appId", clientId);
        httpPost.addHeader("appKey", clientId);
        httpPost.addHeader("accessToken", tokenDTO.getAccess_token());
        httpPost.addHeader("timestamp", u.getTimestamp());
        LOGGER.info("tenantId: " + tenantId);
        httpPost.addHeader("tenantId", tenantId);
        LOGGER.info("initHeader:" + JSONObject.toJSONString(tokenDTO));
    }

    @Override
    public void getTenantInfo() throws UnsupportedEncodingException {
        TokenDTO tokenDTO = getToken();
        List<LinkappTenant> tenantlist = tenantService.selectLinkappTenantList(new LinkappTenant());
        for (LinkappTenant tenant : tenantlist) {
            if (tenant.getAppId() != null && tenant.getAppKey() != null && tenant.getTenantId() != null) {
                QueryWrapper<Application> wrapper = new QueryWrapper<>();
                wrapper.eq("app_key", tenant.getAppKey());
                wrapper.eq("delete_state", 1);
                Application application = applicationService.getOne(wrapper);
                if (application != null) {
                    HttpGet httpGet = new HttpGet(api_url + "/api/user/getTenantInfo");
                    LOGGER.info("appId:" + tenant.getAppId());
                    initHeaderGet(tokenDTO, httpGet, tenant.getAppId(), application.getAppSecret(), tenant.getTenantId());
                    String jsonstr = "";
                    StringEntity se = new StringEntity(jsonstr);
                    se.setContentType("text/json");
                    se.setContentEncoding(new BasicHeader("Content-Type", "application/json"));
                    String str = HttpClientUtil.doGet(httpGet);
                    //LOGGER.info("getTenantInfo:" + str);
                    if (str != null && str.length() > 0) {
                        UserDTO user = JSONObject.parseObject(str, UserDTO.class);
                        if (user != null && user.getData() != null) {
                            TenantDTO tenantDTO = user.getData();
                            UpdateWrapper<LinkappTenant> updateWrapper = new UpdateWrapper<LinkappTenant>();
                            updateWrapper.eq("id", tenant.getId());
                            updateWrapper.set("name", tenantDTO.getName());
                            updateWrapper.set("platform_account", tenantDTO.getAccount());
                            updateWrapper.set("email", tenantDTO.getEmail());
                            updateWrapper.set("app_type", tenantDTO.getVipType());
                            updateWrapper.set("telephone", tenantDTO.getTelephone());
                            updateWrapper.set("platform_project_name", tenantDTO.getPlatformProjectName());
                            updateWrapper.set("platform_account", tenantDTO.getPlatformAccount());
                            updateWrapper.set("platform_account_name", tenantDTO.getPlatformAccountName());
                            updateWrapper.set("app_industry_type", tenantDTO.getAppIndustryType());
                            tenantService.update(updateWrapper);
                        }
                    }
                }
            }
        }
    }

    @Override
    public Boolean updateTenantAccount(LinkappTenant tenant, String account, String newAccount) throws UnsupportedEncodingException {
        TokenDTO tokenDTO = getToken();
        HttpPost httpPost = new HttpPost(api_url + "/api/appBuyList/updateAccount");
        initHeaderPost(tokenDTO, httpPost, tenant.getAppId(), tenant.getAppKey(), tenant.getProjectId());
        Map<String, String> parmMap = new HashMap<>();
        parmMap.put("account", account);
        parmMap.put("newAccount", newAccount);
        String jsonstr = JSON.toJSONString(parmMap);
        jsonstr = new String(jsonstr.getBytes(), StandardCharsets.UTF_8);
        StringEntity se = new StringEntity(jsonstr, StandardCharsets.UTF_8);
        se.setContentType("text/json");
        se.setContentEncoding(new BasicHeader("Content-Type", "application/json"));
        httpPost.setEntity(se);
        LOGGER.info("/api/appBuyList/updateAccount接口请求参数：{}", parmMap);
        String str = HttpClientUtil.doPost(httpPost);
        LOGGER.info("/api/appBuyList/updateAccount接口返回结果：{}:" + str);
        if (str != null) {
            UserDTO userDTO = JSONObject.parseObject(str, UserDTO.class);
            if ("200".equals(userDTO.getCode())) {
                return true;
            }
            return false;
        } else {
            return false;
        }
    }

    /**
     * 初始化HTTP头
     */
    private void initHeader(TokenDTO tokenDTO, HttpGet httpGet) {
        LinkThingsUtil u = new LinkThingsUtil(this.apiKey, this.apiSecret);
        httpGet.addHeader("Content-Type", "application/json");
        httpGet.addHeader("Accept", "application/json");
        httpGet.addHeader("appId", clientId);
        httpGet.addHeader("appKey", clientId);
        httpGet.addHeader("accessToken", tokenDTO.getAccess_token());
        httpGet.addHeader("timestamp", u.getTimestamp());
        httpGet.addHeader("tenantId", tenantId);
        LOGGER.info("initHeader:" + JSONObject.toJSONString(tokenDTO));
    }

    /**
     * 发送数据 -> emp -> 设备 <blockquote>
     *
     * <pre>
     * LinkappOpenApi linkappOpenApi = new LinkappOpenApi();
     * linkappOpenApi.apiKey = "3cea527e085a4298a10fc10d773e00da";
     * linkappOpenApi.apiSecret = "0c63af1024154b7180a11d32fb751c9c";
     * linkappOpenApi.api_url = "http://linkthings-api-out.dev.service.easylinkin.net";
     * ApiDownDTO apiDownDTO = new ApiDownDTO();
     * apiDownDTO.setServiceId("transparent");
     * apiDownDTO.setDeviceId("VIR1587982814060");
     *
     * JSONObject payload = new JSONObject();
     * payload.put("switch_state", "0");
     * apiDownDTO.setPayload(payload.toJSONString());
     * apiDownDTO.setClear(0);
     * apiDownDTO.setConfirm(0);
     * apiDownDTO.setSchedule(0);
     * linkappOpenApi.dataDown(apiDownDTO);
     * </pre>
     *
     * </blockquote>
     */
    @SuppressWarnings("rawtypes")
    @Override
    public ApiDownResultDTO dataDown(Map dto) throws IOException {
        HttpPost httpPost = new HttpPost(String.format("%s/%s", this.api_url, "api/down"));

        initHeaderDown(httpPost);

        StringEntity se = new StringEntity(JSON.toJSONString(dto), "UTF-8");
        se.setContentType("application/json");
        se.setContentEncoding(new BasicHeader("Content-Type", "application/json"));

        httpPost.setEntity(se);
        String str = HttpClientUtil.doPost(httpPost);
        LOGGER.info("dataDown result：{}", str);
        ApiDownResultDTO result = JSON.parseObject(str, ApiDownResultDTO.class);
//		很迷惑 有时返回的是msg  有时是message
        if (result != null && result.getResult() != null && result.getResult().equals(false) && org.apache.commons.lang3.ObjectUtils.isNotEmpty(result.getMessage())) {
            if (org.apache.commons.lang3.ObjectUtils.isEmpty(result.getMsg())) {
                result.setMsg(result.getMessage());
            }
        }

        return result;
    }

    private void initHeaderDown(HttpPost httpPost) {
        LinkThingsUtil u = new LinkThingsUtil(this.apiKey, this.apiSecret);
        String nonce = u.getNonce();
        String signature = u.getSignature();

        httpPost.addHeader("Content-Type", "application/json");
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("api-key", this.apiKey);
        httpPost.addHeader("Nonce", nonce);
        httpPost.addHeader("Signature", signature);
        httpPost.addHeader("timestamp", u.getTimestamp());
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addDevices(List<Device> devices) {
        Assert.notEmpty(devices, "参数列表为空！");
        for (Device device : devices) {
            Assert.notNull(device, "设备参数为空");
            Assert.hasLength(device.getTenantId(), "设备租户id参数为空");
            Assert.hasLength(device.getDeviceUnitCode(), "设备型号code参数为空");
//            也可能存在没有版本号的 只有一个型号
//            Assert.hasLength(device.getDeviceUnitVersion(), "设备型号version参数为空");

            QueryWrapper<DeviceUnit> qw = new QueryWrapper<>();
            qw.eq("code", device.getDeviceUnitCode());
            qw.eq("version", device.getDeviceUnitVersion());
            List<DeviceUnit> deviceUnitList = deviceUnitMapper.selectList(qw);
            Assert.notEmpty(deviceUnitList, "根据型号code：" + device.getDeviceUnitCode() + "，查得型号列表为空，请先完善设备型号的物模型，并去AEP平台主动同步型号！");
            device.setDeviceUnitId(deviceUnitList.get(0).getId());
            deviceService.add(device);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchEraseDevicePositionEtcInfo(Set<String> deviceCodes) {

        Assert.notEmpty(deviceCodes, "参数设备code为空");

        QueryWrapper qw = new QueryWrapper();
        qw.in("code", deviceCodes);

        List<Device> deviceList = deviceMapper.selectList(qw);
        if (ObjectUtils.isEmpty(deviceList)) {
            throw new BusinessException("根据设备编号未查找到设备。");
        }
        for (Device device : deviceList) {
            device.setAreaId(null);
            device.setAreaPath(null);
            device.setIndoorLocation(null);
            device.setLongitude(null);
            device.setLatitude(null);
            deviceService.update(device);
        }

    }

    /**
     * 添加埋点
     *
     * @param buriedPointDTO
     */
    @Override
    public void insertBuriedPoint(BuriedPointDTO buriedPointDTO)
            throws Exception {
        LinkappTenant linkappTenant = tenantService.currentTenant();
        buriedPointDTO.setCreatorId(Long.valueOf(linkappTenant.getProjectId()));

        TokenDTO tokenDTO = getToken();
        HttpPost httpPost = new HttpPost(api_url + "/api/buriedPoint");
        initHeaderPost(tokenDTO, httpPost, this.apiKey, this.apiSecret, this.tenantId);
        StringEntity se = new StringEntity(JSONObject.toJSONString(buriedPointDTO), ContentType.APPLICATION_JSON);
        httpPost.setEntity(se);
        se.setContentType("text/json");
        se.setContentEncoding(new BasicHeader("Content-Type", "application/json"));
        String str = HttpClientUtil.doPost(httpPost);
        LOGGER.info("/api/buriedPoint 的header:" + JSON.toJSONString(httpPost.getAllHeaders()));
        LOGGER.info("/api/buriedPoint 的url:" + httpPost.getURI());
        LOGGER.info("insertBuriedPoint 的结果:" + str);
        if (str == null) {
            return;
        }

    }

    @Override
    public RestMessage getProjectInfo(String project) {
        if (StringUtils.isEmpty(project)) {
            return RestBuilders.failureMessage().setMessage("project 为空");
        }
        //用Id获取
        LinkappTenant linkappTenant = new LinkappTenant();
        linkappTenant.setProjectId(project);
        List<LinkappTenant> linkappTenants = tenantService.selectLinkappTenantList(linkappTenant);
        if (linkappTenants == null || linkappTenants.size() <= 0) {
            //用name获取
            linkappTenant = new LinkappTenant();
            linkappTenant.setPlatformProjectName(project);
            linkappTenants = tenantService.selectLinkappTenantList(linkappTenant);
            if (linkappTenants == null || linkappTenants.size() <= 0) {
                return RestBuilders.failureMessage().setMessage("项目ID或名称不存在");
            }
        }
        //获取租户集合
        Map<String, List<LinkappTenant>> projectMap = linkappTenants.stream().collect(Collectors.groupingBy(LinkappTenant::getProjectId, Collectors.mapping(m -> m, Collectors.toList())));
        List<String> tokenIds = projectMap.entrySet().stream().flatMap(m -> m.getValue().stream().map(LinkappTenant::getId)).collect(Collectors.toList());
        List<LinkappUser> adminTypeUserNameByTenantIds = linkappUserService.findAdminTypeUserNameByTenantIds(tokenIds);
        if (adminTypeUserNameByTenantIds == null || adminTypeUserNameByTenantIds.size() <= 0) {
            return RestBuilders.failureMessage().setMessage("管理员用户不存在");
        }
        Map<String, HashMap<String, Object>> userMap = adminTypeUserNameByTenantIds.stream().collect(Collectors.toMap(m -> m.getTenantId(), m -> {
            HashMap<String, Object> map = new HashMap<>();
            map.put("tenantId", m.getTenantId());
            map.put("token", m.getTenantId());
            map.put("userId", m.getId());
            map.put("userName", m.getUsername());
            return map;
        }, (k1, k2) -> k2));
        HashMap<String, Object> resultMap = new HashMap<>();
        projectMap.entrySet().stream().forEach(m -> {
            ArrayList<Object> objects = new ArrayList<>();
            m.getValue().stream().forEach(t -> {
                HashMap<String, Object> map = null;
                if (userMap == null || userMap.get(t.getId()) == null) {
                    map = new HashMap<>();
                    map.put("tenantId", t.getId());
                } else {
                    map = userMap.get(t.getId());
                }
                map.put("projectId", t.getProjectId());
                map.put("projectName", t.getPlatformProjectName());
                objects.add(map);
            });
            resultMap.put(m.getKey(), objects);
        });
        return RestBuilders.successBuilder().data(resultMap).build();
    }

    /***
     * 获取项目信息
     * @param innerProjectModel
     * @return
     */
    @Override
    public RestMessage getProjectInfo(InnerProjectModel innerProjectModel) {
        if (StringUtils.isEmpty(innerProjectModel.getProjectId()) && StringUtils.isEmpty(innerProjectModel.getProjectName())
                && StringUtils.isEmpty(innerProjectModel.getTenantId()) && StringUtils.isEmpty(innerProjectModel.getUserId())
                && StringUtils.isEmpty(innerProjectModel.getUserName())) {
            return RestBuilders.failureMessage().setMessage("[projectId,tenantId,userName,projectName,userId]不能同时为空");
        }
        List<LinkappTenant> linkappTenants = null;
        if (StringUtils.isNotEmpty(innerProjectModel.getProjectId()) || StringUtils.isNotEmpty(innerProjectModel.getProjectName())) {
            LinkappTenant linkappTenant = new LinkappTenant();
            linkappTenant.setProjectId(innerProjectModel.getProjectId());
            linkappTenant.setPlatformProjectName(innerProjectModel.getProjectName());
            linkappTenants = tenantService.selectLinkappTenantList(linkappTenant);
        }
        if (linkappTenants == null) {
            return getUserProjectInfo(innerProjectModel);
        } else {
            return getProjectInfo(linkappTenants);
        }
    }

    /***
     * 根据用户获取数
     * @param innerProjectModel
     * @return
     */
    private RestMessage getUserProjectInfo(InnerProjectModel innerProjectModel) {
        //获取管理员
        LinkappUser linkappUser = new LinkappUser();
        if (StringUtils.isNotEmpty(innerProjectModel.getUserId())) {
            try {
                linkappUser.setId(Long.valueOf(innerProjectModel.getUserId()));
            } catch (Exception e) {
                return RestBuilders.failureMessage().setMessage("userId 不是数字类型");
            }
        }
        linkappUser.setUsername(innerProjectModel.getUserName());
        linkappUser.setTenantId(innerProjectModel.getTenantId());
        List<LinkappUser> linkappUsers = linkappUserService.selectUsers(linkappUser);
        if (linkappUsers == null || linkappUsers.size() <= 0) {
            return RestBuilders.failureMessage().setMessage("管理员用户不存在");
        }
        Set<String> teanantIds = linkappUsers.stream().filter(m -> StringUtils.isNotBlank(m.getTenantId())).map(LinkappUser::getTenantId).collect(Collectors.toSet());
        if (teanantIds == null || teanantIds.size() <= 0) {
            return RestBuilders.failureMessage().setMessage("租户不存在");
        }
        LinkappTenant linkappTenant = new LinkappTenant();
        linkappTenant.setIds(teanantIds);
        List<LinkappTenant> linkappTenants = tenantService.selectLinkappTenantList(linkappTenant);
        if (linkappTenants == null || linkappTenants.size() <= 0) {
            return RestBuilders.failureMessage().setMessage("租户不存在");
        }
        //获取租户集合
        Map<String, List<LinkappTenant>> projectMap = linkappTenants.stream().filter(m -> StringUtils.isNotEmpty(m.getProjectId())).collect(Collectors.groupingBy(LinkappTenant::getProjectId, Collectors.mapping(m -> m, Collectors.toList())));
        return projectDataHandler(linkappUsers, projectMap);
    }

    /***
     * 根据项目信息获取数据
     * @param linkappTenants
     * @return
     */
    private RestMessage getProjectInfo(List<LinkappTenant> linkappTenants) {
        if (linkappTenants == null || linkappTenants.size() <= 0) {
            return RestBuilders.failureMessage().setMessage("项目ID或名称不存在");
        }
        //获取租户集合
        Map<String, List<LinkappTenant>> projectMap = linkappTenants.stream().collect(Collectors.groupingBy(LinkappTenant::getProjectId, Collectors.mapping(m -> m, Collectors.toList())));
        List<String> tokenIds = projectMap.entrySet().stream().flatMap(m -> m.getValue().stream().map(LinkappTenant::getId)).collect(Collectors.toList());
        List<LinkappUser> adminTypeUserNameByTenantIds = linkappUserService.findAdminTypeUserNameByTenantIds(tokenIds);
        if (adminTypeUserNameByTenantIds == null || adminTypeUserNameByTenantIds.size() <= 0) {
            return RestBuilders.failureMessage().setMessage("管理员用户不存在");
        }
        return projectDataHandler(adminTypeUserNameByTenantIds, projectMap);
    }

    /***
     * 组装返回数据
     * @param adminTypeUserNameByTenantIds
     * @param projectMap
     * @return
     */
    private RestMessage projectDataHandler(List<LinkappUser> adminTypeUserNameByTenantIds, Map<String, List<LinkappTenant>> projectMap) {
        Map<String, HashMap<String, Object>> userMap = adminTypeUserNameByTenantIds.stream().collect(Collectors.toMap(m -> m.getTenantId(), m -> {
            HashMap<String, Object> map = new HashMap<>();
            map.put("tenantId", m.getTenantId());
            map.put("token", m.getTenantId());
            map.put("userId", m.getId());
            map.put("userName", m.getUsername());
            return map;
        }, (k1, k2) -> k2));
        HashMap<String, Object> resultMap = new HashMap<>();
        projectMap.entrySet().stream().forEach(m -> {
            ArrayList<Object> objects = new ArrayList<>();
            m.getValue().stream().forEach(t -> {
                HashMap<String, Object> map = null;
                if (userMap == null || userMap.get(t.getId()) == null) {
                    map = new HashMap<>();
                    map.put("tenantId", t.getId());
                } else {
                    map = userMap.get(t.getId());
                }
                map.put("projectId", t.getProjectId());
                map.put("projectName", t.getPlatformProjectName());
                objects.add(map);
            });
            resultMap.put(m.getKey(), objects);
        });
        return RestBuilders.successBuilder().data(resultMap).build();
    }

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /***
     * 删除AEP
     * @return
     */
    @Override
    @Transactional
    public void deleteAep(Long projectId) {
        //通过项目id找到tenatId
        List<LinkappTenant> linkappTenantList = linkappTenantMapper.selectByProjectId(String.valueOf(projectId));
        if (null != linkappTenantList && linkappTenantList.size() > 0) {
            linkappTenantList.forEach(linkappTenant -> {
                if (null != linkappTenant && null != linkappTenant.getId()) {
                    //linkapp_personality数据
                    if (StringUtils.isNotBlank(linkappTenant.getPersonalityId())) {
                        personalityMapper.deleteById(linkappTenant.getPersonalityId());
                    }
                    String id = linkappTenant.getId();
                    //删除对应的表数据
                    Map<String, Object> map = new HashMap<>();
                    map.put("tenant_id", id);
                    linkappTenantMapper.deleteById(linkappTenant.getId());
                    linkappUserMapper.deleteByMap(map);
                    assetMapper.deleteByMap(map);
                    airHostDeviceMapper.deleteByMap(map);
                    airconditionDeviceRecordMapper.deleteByMap(map);
                    calculateConfigAttributeMapper.deleteByMap(map);
                    personnelMapper.deleteByMap(map);
                    personnelIdentifierMapper.deleteByMap(map);
                    recognitionRecordMapper.deleteByMap(map);
                    investigationTaskDetailMapper.deleteByMap(map);
                    investigationTaskModelMapper.deleteByMap(map);
                    distributionElectricPriceMapper.deleteByMap(map);
                    ruleComponentAttributeMapper.deleteByMap(map);
                    aquacultureSpaceMapper.deleteByMap(map);
                    areasourceecologyFunctionMapper.deleteByMap(map);
                    carManageMapper.deleteByMap(map);
                    tenantFunctionRefAreaMapper.deleteByMap(map);
                    livestockFarmingMapper.deleteByMap(map);
                    linkappTenantSessionConfigMapper.deleteByMap(map);
                    linkappAreaMapper.deleteByMap(map);
                    functionMapper.deleteFunctions2Tenant(id);
                    linkappTenantMapper.deleteTenant2Privileges(id, 0);
                    //删除设备
                    deviceMapper.deleteByMap(map);
                    deviceMapper.deleteInfo(id);
                    deviceAttributeTenantConfigMapper.deleteByMap(map);
                    deviceParmDictionaryMapper.deleteByMap(map);
                    deviceServiceTenantConfigMapper.deleteByMap(map);
                    //删除机械台账
                    machineryRecordService.deleteByMap(map);
                    //删除规则引擎
                    ruleEngineMapper.deleteByMap(map);
                    //执行自定义sql
                    String deleteSal =
                            //劳务管理
                            "DELETE from app_user_project where tenant_id_ = 'deleteByTenantId';"
                            + "DELETE from app_labor_company_project where tenant_id_ = 'deleteByTenantId';"
                            + "DELETE from app_group where tenant_id_ = 'deleteByTenantId';"
                            + "DELETE from app_user_clock where tenant_id_ = 'deleteByTenantId';"
                            + "DELETE from app_user_gate where tenant_id_ = 'deleteByTenantId';"
                            + "DELETE from app_user_record where tenant_id_ = 'deleteByTenantId';"
                            + "DELETE from app_user_statistics where tenant_id_ = 'deleteByTenantId';";
                    //替换deleteByTenantId为TenantId
                    String[] sqls = deleteSal.replaceAll("deleteByTenantId", id)
                            .split(";");
                    Arrays.stream(sqls).forEach(sql -> {
                                try {
                                    jdbcTemplate.execute(sql);
                                } catch (DataAccessException e) {
                                    //防止其中一个表不存在，导致事件回滚
                                    e.printStackTrace();
                                }
                            }
                    );
                }
            });
        }

    }

    /**
     * 同步用户基本信息到linkthings
     * @param empUserBase
     * @return
     */
    @Override
    public ApiDownResultDTO syncUser(EmpUserBase empUserBase) {
        HttpPost httpPost = new HttpPost(String.format("%s/%s", this.api_url, "api/syncUser"));
        initHeaderDown(httpPost);
        StringEntity se = new StringEntity(JSON.toJSONString(empUserBase), "UTF-8");
        se.setContentType("application/json");
        se.setContentEncoding(new BasicHeader("Content-Type", "application/json"));
        httpPost.setEntity(se);
        String str = HttpClientUtil.doPost(httpPost);
        LOGGER.info("dataDown result：{}", str);
        ApiDownResultDTO result = JSON.parseObject(str, ApiDownResultDTO.class);
//		很迷惑 有时返回的是msg  有时是message
        if (result != null && result.getResult() != null && result.getResult().equals(false) && org.apache.commons.lang3.ObjectUtils.isNotEmpty(result.getMessage())) {
            if (org.apache.commons.lang3.ObjectUtils.isEmpty(result.getMsg())) {
                result.setMsg(result.getMessage());
            }
        }
        return result;
    }


    @Override
    public IPage<DeviceAttributeStatus> getDeviceVideoList(Long projectId) {
        // 同过 项目ID 查询 租户ID
        LinkappTenant tenant = tenantService.getOneByProjectId(projectId);
        Assert.notNull(tenant, "根据项目id 查询租户为空");
        Device device = new Device().setTenantId(tenant.getId());
        IPage<DeviceAttributeStatus> deviceVideoList = deviceAreaHandlerService.getDeviceVideoList(new Page(0, -1), device);
        List<DeviceAttributeStatus> res = deviceVideoList.getRecords().stream().sorted(new Comparator<DeviceAttributeStatus>() {
            @Override
            public int compare(DeviceAttributeStatus o1, DeviceAttributeStatus o2) {
                if (o1.getCreateTime() == null) {
                    return 1;
                }
                if (o2.getCreateTime() == null) {
                    return -1;
                }
                return o2.getCreateTime().compareTo(o1.getCreateTime());
            }
        }).collect(Collectors.toList());
        deviceVideoList.setRecords(res);
        return deviceVideoList;
    }

    @Override
    public LinkappTenant getAepTenantInfo(Long projectId) {
        LinkappTenant tenant = tenantService.getOneByProjectId(projectId);
        return tenant;
    }

    @Override
    public List<CameraCountByProjectDTO> getCameraCountByProjectIds(List<Long> projectIds) {
        List<CameraCountByProjectDTO> list = deviceMapper.getCameraCountByProjectIds(projectIds);
        return list;
    }

    @Override
    public Map<String, List<SafetyCheckTrendDTO>> selectSafetyCheckTrend() {
        Map<String, List<SafetyCheckTrendDTO>> map = new HashMap(4);
        LinkedList<SafetyCheckTrendDTO> list1 = new LinkedList<>();
        LinkedList<SafetyCheckTrendDTO> list2 = new LinkedList<>();
        Calendar nearMonday = getNearMonday();
        Calendar nearSunday = Calendar.getInstance();
        nearSunday.setTime(nearMonday.getTime());
        nearSunday.add(Calendar.DATE, 6);

        for (int i = 12; i > 0; i--) {
            String start = DateUtil.format(nearMonday.getTime(), "yyyy-MM-dd");
            String end = DateUtil.format(nearSunday.getTime(), "yyyy-MM-dd");
            list1.offerFirst(new SafetyCheckTrendDTO(start, end, 0));
            list2.offerFirst(new SafetyCheckTrendDTO(start, end, 0));
            nearMonday.add(Calendar.DATE, -7);
            nearSunday.add(Calendar.DATE, -7);
        }
        list1.getLast().setDateEnd(DateUtil.format(Calendar.getInstance().getTime(), "yyyy-MM-dd"));
        list2.getLast().setDateEnd(DateUtil.format(Calendar.getInstance().getTime(), "yyyy-MM-dd"));


        Date end = Calendar.getInstance().getTime();
        Calendar startCal = Calendar.getInstance();
        startCal.add(Calendar.MONTH, -4);
        Date start = startCal.getTime();
        List<SafetyCheckTrendDTO> query1 = hiddenDangerMapper.selectSafetyCheckTrend(start, end, new HiddenDanger());
        List<SafetyCheckTrendDTO> query2 = hiddenDangerMapper.selectSafetyCheckTrend(start, end, new HiddenDanger().setEnterpriseSourceType(2));
        Map<String, List<SafetyCheckTrendDTO>> map1 = query1.stream().collect(Collectors.groupingBy(SafetyCheckTrendDTO::getDateStr));
        Map<String, List<SafetyCheckTrendDTO>> map2 = query2.stream().collect(Collectors.groupingBy(SafetyCheckTrendDTO::getDateStr));
        map1.forEach((k, v) -> {
                    for (SafetyCheckTrendDTO safetyCheckTrendDTO : list1) {
                        if (k.compareTo(safetyCheckTrendDTO.getDateStart()) >= 0 && k.compareTo(safetyCheckTrendDTO.getDateEnd()) <= 0) {
                            safetyCheckTrendDTO.setCountNum(safetyCheckTrendDTO.getCountNum() + v.get(0).getCountNum());
                            break;
                        }
                    }
                }
        );
        map2.forEach((k, v) -> {
                    for (SafetyCheckTrendDTO safetyCheckTrendDTO : list2) {
                        if (k.compareTo(safetyCheckTrendDTO.getDateStart()) >= 0 && k.compareTo(safetyCheckTrendDTO.getDateEnd()) <= 0) {
                            safetyCheckTrendDTO.setCountNum(safetyCheckTrendDTO.getCountNum() + v.get(0).getCountNum());
                            break;
                        }
                    }
                }
        );

        map.put("project", list1);
        map.put("enterprise", list2);
        return map;
    }


    private Calendar getNearMonday() {
        Calendar cal = Calendar.getInstance();
        while (Calendar.MONDAY != cal.get(Calendar.DAY_OF_WEEK)){
            cal.add(Calendar.DAY_OF_MONTH,-1);
        }
        return cal;
    }

    @Override
    public List<BigScreenStatisticDTO> selectSafetyCheckCategoryByName(Date start, Date end) {
        List<BigScreenStatisticDTO> list = hiddenDangerMapper.selectSafetyCheckCategoryByName(start, end);
        //进行参数重新处理
        if(CollectionUtil.isNotEmpty(list)){
            list.forEach(item->{
                if(StringUtils.isNotBlank(item.getName_())){
                    item.setName(item.getName_());
                }
            });
        }
        double sum = list.stream().mapToDouble(BigScreenStatisticDTO::getCountNum).sum();
        LOGGER.info("sum: "+sum);
        if (sum > 0) {
            for (BigScreenStatisticDTO bigScreenStatisticDTO : list) {
                BigDecimal big = BigDecimal.valueOf(bigScreenStatisticDTO.getCountNum() * 100).divide(BigDecimal.valueOf(sum), 2, RoundingMode.HALF_UP);
                bigScreenStatisticDTO.setRate(big.doubleValue());
            }
        }
        return list;
    }


    @Override
    public List<BigScreenStatisticDTO> selectAlarmStatistic(Date start, Date end) {
        List<BigScreenStatisticDTO> list = alarmMapper.selectAlarmStatisticGlobal(start, end);
        if (list.size() > 6) {
            int sum = list.stream().mapToInt(BigScreenStatisticDTO::getCountNum).sum();
            List<BigScreenStatisticDTO> sub = list.subList(0, 5);
            int subSum = 0;
            BigDecimal rate = BigDecimal.valueOf(100);
            for (BigScreenStatisticDTO bigScreenStatisticDTO : sub) {
                subSum += bigScreenStatisticDTO.getCountNum();
                rate = rate.subtract(BigDecimal.valueOf(bigScreenStatisticDTO.getRate()));
            }
            sub.add(new BigScreenStatisticDTO("其余", sum - subSum, rate.doubleValue()));
            return sub;
        }
        return list;
    }

    @Resource
    DangerousInfoMapper dangerousInfoMapper;
    @Override
    public List<BigScreenStatisticDTO> selectDangerousStatistic(DangerousInfo dangerous) {
        List<BigScreenStatisticDTO> list = dangerousInfoMapper.selectDangerousStatistic(dangerous);
        double sum = list.stream().mapToDouble(BigScreenStatisticDTO::getCountNum).sum();
        if (sum > 0) {
            for (BigScreenStatisticDTO bigScreenStatisticDTO : list) {
                BigDecimal big = BigDecimal.valueOf(bigScreenStatisticDTO.getCountNum() * 100).divide(BigDecimal.valueOf(sum), 2, RoundingMode.HALF_UP);
                bigScreenStatisticDTO.setRate(big.doubleValue());
            }
        }
        return list;
    }



    @Override
    public SafetyCheckCategory selectSafetyCheckCategory(Date startTime, Date endTime) {
        return hiddenDangerMapper.selectSafetyCheckCategory(startTime,endTime);
    }

    @Override
    public List<ProjectStatisticDTO> selectProjectStatisticList(ProjectDTO projectDTO) {
        List<ProjectStatisticDTO> list = selectProjectStatisticListFromEdu(projectDTO);
        for (ProjectStatisticDTO projectStatisticDTO : list) {
            Calendar now = Calendar.getInstance();
            now.set(Calendar.HOUR_OF_DAY, 0);
            now.set(Calendar.MINUTE, 0);
            now.set(Calendar.SECOND, 0);
            now.set(Calendar.MILLISECOND, 0);
            if (projectStatisticDTO.getStartTime() != null) {
                Calendar start = Calendar.getInstance();
                start.setTime(projectStatisticDTO.getStartTime());
                start.set(Calendar.HOUR_OF_DAY, 0);
                start.set(Calendar.MINUTE, 0);
                start.set(Calendar.SECOND, 0);
                start.set(Calendar.MILLISECOND, 0);
                int pd = 1 + (int) DateUtil.between(start.getTime(), now.getTime(), DateUnit.DAY, false);
                projectStatisticDTO.setProductDays(Math.max(pd, 0));
            }
            if (projectStatisticDTO.getEndTime() != null) {
                Calendar end = Calendar.getInstance();
                end.setTime(projectStatisticDTO.getEndTime());
                end.set(Calendar.HOUR_OF_DAY, 0);
                end.set(Calendar.MINUTE, 0);
                end.set(Calendar.SECOND, 0);
                end.set(Calendar.MILLISECOND, 0);
                projectStatisticDTO.setLeftDays((int) DateUtil.between(now.getTime(), end.getTime(), DateUnit.DAY, false));
            }
        }
        List<ProjectStatisticDTO> checkNumList = hiddenDangerMapper.selectCheckNumAndCloseRate();
        Map<Long, List<ProjectStatisticDTO>> checkNumListMap = checkNumList.stream().collect(Collectors.groupingBy(ProjectStatisticDTO::getId));

        List<ProjectStatisticDTO> dangerProjectNumList = dangerousInfoMapper.selectDangerProjectNum();
        Map<Long, List<ProjectStatisticDTO>> dangerProjectNumListMap = dangerProjectNumList.stream().collect(Collectors.groupingBy(ProjectStatisticDTO::getId));

        for (ProjectStatisticDTO statisticDTO : list) {
            List<ProjectStatisticDTO> list0 = checkNumListMap.get(statisticDTO.getId());
            if (!ObjectUtils.isEmpty(list0)) {
                statisticDTO.setCheckNum(list0.get(0).getCheckNum());
                statisticDTO.setCloseRate(list0.get(0).getCloseRate());
            }
            List<ProjectStatisticDTO> list2 = dangerProjectNumListMap.get(statisticDTO.getId());
            if (!ObjectUtils.isEmpty(list2)) {
                statisticDTO.setDangerProjectNum(list2.get(0).getDangerProjectNum());
            }
        }
        return list;
    }

    /**
     * 大屏-查询项目列表 向 edu请求
     */
    private List<ProjectStatisticDTO> selectProjectStatisticListFromEdu(ProjectDTO projectDTO) {
        HttpPost httpPost = new HttpPost(apiUrl + "/enterpriseOpenApi/dashBoard/selectProjectStatisticListFromEdu");
        StringEntity se = new StringEntity(JSONObject.toJSONString(projectDTO), ContentType.APPLICATION_JSON);
        LOGGER.info("/selectProjectStatisticListFromEdu 的header:" + JSON.toJSONString(httpPost.getAllHeaders()));
        LOGGER.info("/selectProjectStatisticListFromEdu 的url:" + httpPost.getURI());
        httpPost.setEntity(se);
        String str = HttpClientUtil.doPost(httpPost);
        if (str == null) {
            return Collections.emptyList();
        }
        List<ProjectStatisticDTO> list = JSON.parseArray(str, ProjectStatisticDTO.class);
        return list;
    }

}
